package com.nickstumpos.android.GmailWidgetPlus.widget.presentation.managers.displaylabels;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.PendingIntent;
import android.content.Context;

import com.nickstumpos.android.GmailWidgetPlus.Constants.GMWP_Constants;
import com.nickstumpos.android.GmailWidgetPlus.labels.LabelCountPair;
import com.nickstumpos.android.GmailWidgetPlus.widget.presentation.managers.SimpleLabel;
import com.nickstumpos.android.GmailWidgetPlus.widget.presentation.managers.WidgetUIData;
import com.nickstumpos.android.GmailWidgetPlus.widget.sizes.WidgetSize;
import com.nickstumpos.android.GmailWidgetPlus.widget.skins.WidgetSkin;
import com.nickstumpos.android.GmailWidgetPlus.widget.skins.WidgetSkins;

public abstract class AWidgetWithLabelsUIManager extends
		AWidgetWithUnreadCountUIManager {

	private Map<WidgetSkin, Integer>	startIndex;
	private final int					noUnreadMailButton;
	private final int					noUnreadMailText;
	private final int					upButton;
	private final int					upButtonDisabled;
	private final int					downButton;
	private final int					downButtonDisabled;
	private List<LabelCountPair>		labels	= null;

	protected AWidgetWithLabelsUIManager(final Context context,
			final WidgetUIData wData) {
		super(context,
				wData.getAccount(),
				wData.getWidgetId(),
				wData.getUnreadCountButton());
		this.noUnreadMailButton = wData.getNoUnreadMailButton();
		this.noUnreadMailText = wData.getNoUnreadMailText();
		this.upButton = wData.getUpButton();
		this.upButtonDisabled = wData.getUpButtonDisabled();
		this.downButton = wData.getDownButtonDisabled();
		this.downButtonDisabled = wData.getDownButtonDisabled();
		this.initMaps();
		this.initUnreadButtonIntent();
		this.initArrowButtonIntents();
	}

	protected Boolean changeCurrentStartIndex(final int delta) {

		Boolean ret = false;
		if ((this.getWidgetSkin() != null) && (this.labels != null)
				&& (this.startIndex != null)) {
			final int possibleValue = this.getCurrentStartIndex() + delta;
			if ((possibleValue >= 0) && (possibleValue + this.getWidgetSkin()
					.totalShowingLabels() <= this.labels.size())) {
				this.startIndex.put(this.getWidgetSkin(),
						this.getCurrentStartIndex() + delta);
				ret = true;
			}
		}
		return ret;
	}

	protected void displayLabelsWithUnreadMail() {
		for (final SimpleLabel label : this.getLabelViewData()) {
			final int loc = label.getPosition() + this.getCurrentStartIndex();
			if (loc < this.labels.size()) {
				this.setViewText(label.getLabelViewID(), this.labels.get(loc)
						.toString());
				this.setViewText(label.getUnreadViewID(),
						"(" + this.labels.get(loc).getCount() + ")");
				final PendingIntent openLabel = this.getGMWPIntents()
						.openGmailLabelIntent(this.labels.get(loc).getLabel());
				this.setClickAction(label.getOuterId(), openLabel);
				this.showLabel(label);
			} else {
				this.hideLabel(label);
			}
		}
	}

	protected int getCurrentStartIndex() {
		int ret = 0;
		if ((this.startIndex != null) && (this.getWidgetSkin() != null)) {
			ret = this.startIndex.get(this.getWidgetSkin());
		}
		return ret;
	}

	protected List<LabelCountPair> getLabels() {
		return this.labels;
	}

	public abstract List<SimpleLabel> getLabelViewData();

	protected abstract WidgetSize getWidgetSize();

	protected Boolean hasMoreLabelsAhead() {
		if (this.getCurrentStartIndex() + this.getWidgetSkin()
				.totalShowingLabels() < this.labels.size()) {
			return true;
		}
		return false;
	}

	protected Boolean hasMoreLabelsBehind() {
		if ((this.getCurrentStartIndex() > 0) && (this.getWidgetSkin()
				.totalShowingLabels() < this.labels.size())) {
			return true;
		}
		return false;
	}

	protected void hideAllLabels() {
		for (final SimpleLabel label : this.getLabelViewData()) {
			this.hideLabel(label);
		}
	}

	protected void hideLabel(final SimpleLabel label) {
		this.hideView(label.getOuterId());
		this.hideView(label.getLabelViewID());
		this.hideView(label.getHrID());
		this.hideView(label.getUnreadViewID());
	}

	protected void hideNoMailButton() {
		this.hideView(this.noUnreadMailButton);
	}

	private void initArrowButtonIntents() {
		this.setClickAction(this.upButton, this.getGMWPIntents()
				.newGMWPBroadcastIntent(GMWP_Constants.WIDGET_DN));
		this.setClickAction(this.upButton, this.getGMWPIntents()
				.newGMWPBroadcastIntent(GMWP_Constants.WIDGET_UP));
	}

	private void initMaps() {
		this.startIndex = new HashMap<WidgetSkin, Integer>();
		for (final WidgetSkins t : WidgetSkins.values()) {
			this.startIndex.put(t, 0);
		}
	}

	protected abstract int labelIncrementAmount();

	@Override
	public void nextLabelSet() {
		this.changeCurrentStartIndex(this.labelIncrementAmount());
		this.loadChange();
	}

	@Override
	public void previousLabelSet() {
		this.changeCurrentStartIndex(-this.labelIncrementAmount());
		this.loadChange();
	}

	protected void refreshLabelsAndCounts(final List<LabelCountPair> labels) {
		this.labels = labels;
	}

	public void setArrowButtonStates() {

		if (this.hasMoreLabelsBehind()) {
			this.hideView(this.upButtonDisabled);
			this.showView(this.upButton);
		} else {
			this.hideView(this.upButton);
			this.showView(this.upButtonDisabled);
		}
		if (this.hasMoreLabelsAhead()) {
			this.showView(this.downButton);
			this.hideView(this.downButtonDisabled);
		} else {
			this.hideView(this.downButton);
			this.showView(this.downButtonDisabled);
		}
	}

	public void setLabels(final List<LabelCountPair> labels) {
		this.labels = labels;
	}

	protected void showDisabledMessage() {
		this.setViewText(this.noUnreadMailText, GMWP_Constants.NO_ACCT_MSG);
		this.showView(this.noUnreadMailButton);
		final PendingIntent dummy = this.getGMWPIntents().newDummyIntent();
		this.setClickAction(this.noUnreadMailButton, dummy);
	}

	protected void showLabel(final SimpleLabel label) {
		this.showView(label.getOuterId());
		this.showView(label.getLabelViewID());
		this.showView(label.getHrID());
		this.showView(label.getUnreadViewID());
	}

	protected void showNoMailButton() {
		this.setViewText(this.noUnreadMailText, GMWP_Constants.NO_UNREAD_MSG);
		this.showView(this.noUnreadMailButton);
		final PendingIntent openInbox = this.getGMWPIntents()
				.openGmailLabelIntent("^i");
		this.setClickAction(this.noUnreadMailButton, openInbox);
	}
}
